using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Castle.Core.Interceptor;

namespace WindsorDuckTyping {
    public class DuckTypingInterceptor : IInterceptor {
        private readonly object target;
        private readonly Dictionary<KeyValuePair<MethodInfo, Type[]>, MethodInfo> methods = new Dictionary<KeyValuePair<MethodInfo, Type[]>, MethodInfo>();

        public DuckTypingInterceptor(object target, Type targetType) {
            this.target = target;
            BuildMethodDictionary(target.GetType(), targetType);
        }

        public void BuildMethodDictionary(Type type, Type targetType) {
            //type.GetMethods()[0].GetGenericArguments()
            throw new NotImplementedException();
        }

        public void Intercept(IInvocation invocation) {
            var methods = target.GetType().GetMethods()
                .Where(m => m.Name == invocation.Method.Name)
                .Where(m => m.GetParameters().Length == invocation.Arguments.Length)
                .ToList();
            if (methods.Count > 1)
                throw new ApplicationException(string.Format("Ambiguous method match for '{0}'", invocation.Method.Name));
            if (methods.Count == 0)
                throw new ApplicationException(string.Format("No method '{0}' found", invocation.Method.Name));
            var method = methods[0];
            if (invocation.GenericArguments != null && invocation.GenericArguments.Length > 0)
                method = method.MakeGenericMethod(invocation.GenericArguments);
            invocation.ReturnValue = method.Invoke(target, invocation.Arguments);
        }
    }
}